package FoldFIFO (
                 FoldFIFO(..),
                 mkFoldFIFO
                 ) where

-- foldable FIFO

--@ XXX THIS PACKAGE IS NOT YET DOCUMENTED

interface FoldFIFO a =
  enq   :: a -> Action
  deq   :: Action
  first :: a
  clear :: Action
  foldr :: (a -> b -> b) -> b -> b

mkFoldFIFO :: (IsModule m c, Bits a k) => m (FoldFIFO a)
mkFoldFIFO =
  module
    v :: Reg a
    v <- mkRegU
    f :: Reg Bool
    f <- mkReg False
    interface
      enq x  = action { f := True; v := x }    when not f
      deq    = action { f := False }           when f
      first  = v                               when f
      clear  = action { f := False }
      foldr g z = if f
                  then g v z
                  else z
